package timing.ukulele.gateway.service;

import timing.ukulele.common.ResponseResult;
import timing.ukulele.common.dictionary.RoleEnum;
import timing.ukulele.common.portal.UserData;
import timing.ukulele.common.util.DictionaryUtil;
import timing.ukulele.gateway.client.PortalClient;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;

@Component
public class SecurityUserDetailsService implements ReactiveUserDetailsService {

    @Resource
    private PortalClient portalClient;

    private String[] roles;


    @PostConstruct
    private void setRoles() {
        roles = DictionaryUtil.all(RoleEnum.class);
    }

    @Override
    public Mono<UserDetails> findByUsername(String username) {
//        final ResponseResult<UserData> result = portalClient.findByUsername(username);
        CompletableFuture<ResponseResult<UserData>> completableFuture = CompletableFuture.supplyAsync(() -> portalClient.findByUsername(username));
        try {
            final ResponseResult<UserData> result = completableFuture.get();
            if (result != null && result.getData() != null) {
                UserData data = result.getData();
                String role = DictionaryUtil.get(RoleEnum.class, data.getRoleId().shortValue());
                UserDetails user = User.withUsername(username)
                        .password(data.getPassword())
                        .roles(roles)
                        .authorities(role)
                        .build();
                return Mono.just(user);
            } else {
                return Mono.error(new UsernameNotFoundException("User Not Found"));
            }
        } catch (Exception e) {
            return Mono.error(new UsernameNotFoundException("User Not Found"));
        }
    }
}
